﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Tk.Soc.Share.Common.Helpers
{
    /// <summary>
    /// 标记属性的别名Title
    /// </summary>
    public class AttrForCsvColumnLabel : Attribute
    {
        public string Title { get; set; }
    }

    public static class CsvFileUtility
    {

        public static StringBuilder SaveDataToCSVFile<T>(List<T> dataList) where T : class
        {
         
            StringBuilder sb_Text = new StringBuilder();
            StringBuilder strColumn = new StringBuilder();
            StringBuilder strValue = new StringBuilder();
            StreamWriter sw = null;
            var tp = typeof(T);
            PropertyInfo[] props = tp.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            try
            {
                List<int> noAttrs = new List<int>();
                for (int i = 0; i < props.Length; i++)
                {
                    var itemPropery = props[i];
                    AttrForCsvColumnLabel labelAttr = itemPropery.GetCustomAttributes(typeof(AttrForCsvColumnLabel), true).FirstOrDefault() as AttrForCsvColumnLabel;
                    if (null != labelAttr)
                    {
                        strColumn.Append(labelAttr.Title);
                        strColumn.Append(",");
                    }
                    else
                    {
                        //strColumn.Append(props[i].Name);
                        noAttrs.Add(i);
                    }
             

                }
                strColumn.Remove(strColumn.Length - 1, 1);
                sb_Text.AppendLine(strColumn.ToString());

                for (int i = 0; i < dataList.Count; i++)
                {
                    var model = dataList[i];
                    strValue.Clear();
                    int num = 0;
                    for (int m = 0; m < props.Length; m++)
                    {
                        if (noAttrs.Contains(m))
                        {
                            continue;
                        }
                        num++;
                        string val = null;
                        var itemPropery = props[m];
                        var data = itemPropery.GetValue(model, null);
                        if (data == null) 
                        {
                            val="";
                        }else if (data.GetType() == typeof(DateTime))
                        {
                            val = ((DateTime)data).ToString("yyyy-MM-dd HH:mm:ss");
                        }
                        else
                        {
                            val = data.ToString().Replace(',', '，');
                        }
                        if (num == 1)
                        {
                            strValue.Append(val);
                        }
                        else
                        {
                            strValue.Append(",");
                            strValue.Append(val);
                        }
                    }
                    sb_Text.AppendLine(strValue.ToString());
                }
                return sb_Text;
            }
            catch (Exception ex)
            {
                LogHelper.Logger.Error("转化文件失败"+ex.Message);
                return null ;
            }
            finally
            {
                if (sw != null)
                {
                    sw.Dispose();
                }
            }
            
        }

        public static bool SaveDataToCSVFile<T>(List<T> dataList, string path) where T : class
        {
            bool successFlag = true;
            var filePath = System.IO.Path.GetDirectoryName(path);
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            StringBuilder sb_Text = new StringBuilder();
            StringBuilder strColumn = new StringBuilder();
            StringBuilder strValue = new StringBuilder();
            StreamWriter sw = null;
            var tp = typeof(T);
            PropertyInfo[] props = tp.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            try
            {
                for (int i = 0; i < props.Length; i++)
                {
                    var itemPropery = props[i];
                    AttrForCsvColumnLabel labelAttr = itemPropery.GetCustomAttributes(typeof(AttrForCsvColumnLabel), true).FirstOrDefault() as AttrForCsvColumnLabel;
                    if (null != labelAttr)
                    {
                        strColumn.Append(labelAttr.Title);
                    }
                    else
                    {
                        strColumn.Append(props[i].Name);
                    }

                    strColumn.Append(",");
                }
                strColumn.Remove(strColumn.Length - 1, 1);
                sb_Text.AppendLine(strColumn.ToString());

                for (int i = 0; i < dataList.Count; i++)
                {
                    var model = dataList[i];
                    strValue.Clear();
                    for (int m = 0; m < props.Length; m++)
                    {
                        string val = null;
                        var itemPropery = props[m];
                        var data = itemPropery.GetValue(model, null);

                        if (data.GetType() == typeof(DateTime))
                        {
                            val = ((DateTime)data).ToString("yyyy-MM-dd HH:mm:ss");
                        }
                        else
                        {
                            val = data.ToString().Replace(',', '，');
                        }
                        if (m == 0)
                        {
                            strValue.Append(val);
                        }
                        else
                        {
                            strValue.Append(",");
                            strValue.Append(val);
                        }
                    }
                    sb_Text.AppendLine(strValue.ToString());
                }

                File.WriteAllText(path, sb_Text.ToString(), Encoding.UTF8);
            }
            catch (Exception ex)
            {
                successFlag = false;
            }
            finally
            {
                if (sw != null)
                {
                    sw.Dispose();
                }
            }
            return successFlag;
        }
    }
}
